import './index.css'
import { useDark, isNumber, isFunction, useResizeObserver } from '@pureadmin/utils'
import { type PropType, h, ref, toRef, watch, nextTick, defineComponent, getCurrentInstance } from 'vue'
import { useRenderIcon } from '@/components/ReIcon/src/hooks'
import type { OptionsType } from './type'

const props = {
  options: {
    type: Array<OptionsType>,
    default: () => [],
  },
  /** 默认选中，按照第一个索引为 `0` 的模式，可选（`modelValue`只有传`number`类型时才为响应式） */
  modelValue: {
    type: undefined,
    require: false,
    default: '0',
  },
  /** 将宽度调整为父元素宽度	 */
  block: {
    type: Boolean,
    default: false,
  },
  /** 控件尺寸 */
  size: {
    type: String as PropType<'small' | 'default' | 'large'>,
  },
  /** 是否全局禁用，默认 `false` */
  disabled: {
    type: Boolean,
    default: false,
  },
  /** 当内容发生变化时，设置 `resize` 可使其自适应容器位置 */
  resize: {
    type: Boolean,
    default: false,
  },
}

export default defineComponent({
  name: 'ReSegmented',
  props,
  emits: ['change', 'update:modelValue'],
  setup(props, { emit }) {
    const width = ref(0)
    const translateX = ref(0)
    const { isDark } = useDark()
    const initStatus = ref(false)
    const curMouseActive = ref(-1)
    const segmentedItembg = ref('')
    const instance = getCurrentInstance()!
    const curIndex = isNumber(props.modelValue) ? toRef(props, 'modelValue') : ref(0)

    function handleChange({ option, index }, event: Event) {
      if (props.disabled || option.disabled) return
      event.preventDefault()
      isNumber(props.modelValue) ? emit('update:modelValue', index) : (curIndex.value = index)
      segmentedItembg.value = ''
      emit('change', { index, option })
    }

    function handleMouseenter({ option, index }, event: Event) {
      if (props.disabled) return
      event.preventDefault()
      curMouseActive.value = index
      if (option.disabled || curIndex.value === index) {
        segmentedItembg.value = ''
      } else {
        segmentedItembg.value = isDark.value ? '#1f1f1f' : 'rgba(0, 0, 0, 0.06)'
      }
    }

    function handleMouseleave(_, event: Event) {
      if (props.disabled) return
      event.preventDefault()
      curMouseActive.value = -1
    }

    function handleInit(index = curIndex.value) {
      nextTick(() => {
        const curLabelRef = instance?.proxy?.$refs[`labelRef${index}`] as ElRef
        if (!curLabelRef) return
        width.value = curLabelRef.clientWidth
        translateX.value = curLabelRef.offsetLeft
        initStatus.value = true
      })
    }

    function handleResizeInit() {
      useResizeObserver('.pure-segmented', () => {
        nextTick(() => {
          handleInit(curIndex.value)
        })
      })
    }

    ;(props.block || props.resize) && handleResizeInit()

    watch(
      () => curIndex.value,
      (index) => {
        nextTick(() => {
          handleInit(index)
        })
      },
      {
        immediate: true,
      }
    )

    watch(() => props.size, handleResizeInit, {
      immediate: true,
    })

    const rendLabel = () => {
      return props.options.map((option, index) => {
        return (
          <label
            ref={`labelRef${index}`}
            class={['pure-segmented-item', (props.disabled || option?.disabled) && 'pure-segmented-item-disabled']}
            style={{
              background: curMouseActive.value === index ? segmentedItembg.value : '',
              color: props.disabled
                ? null
                : !option.disabled && (curIndex.value === index || curMouseActive.value === index)
                  ? isDark.value
                    ? 'rgba(255, 255, 255, 0.85)'
                    : 'rgba(0,0,0,.88)'
                  : '',
            }}
            onMouseenter={(event) => handleMouseenter({ option, index }, event)}
            onMouseleave={(event) => handleMouseleave({ option, index }, event)}
            onClick={(event) => handleChange({ option, index }, event)}
          >
            <input type="radio" name="segmented" />
            <div
              class="pure-segmented-item-label"
              v-tippy={{
                content: option?.tip,
                zIndex: 41000,
              }}
            >
              {option.icon && !isFunction(option.label) ? (
                <span class="pure-segmented-item-icon" style={{ marginRight: option.label ? '6px' : 0 }}>
                  {h(
                    useRenderIcon(option.icon, {
                      ...option?.iconAttrs,
                    })
                  )}
                </span>
              ) : null}
              {option.label ? isFunction(option.label) ? h(option.label) : <span>{option.label}</span> : null}
            </div>
          </label>
        )
      })
    }

    return () => (
      <div
        class={{
          'pure-segmented': true,
          'pure-segmented-block': props.block,
          'pure-segmented--large': props.size === 'large',
          'pure-segmented--small': props.size === 'small',
        }}
      >
        <div class="pure-segmented-group">
          <div
            class="pure-segmented-item-selected"
            style={{
              width: `${width.value}px`,
              transform: `translateX(${translateX.value}px)`,
              display: initStatus.value ? 'block' : 'none',
            }}
          ></div>
          {rendLabel()}
        </div>
      </div>
    )
  },
})
